using System.Text;
using System.Security.Cryptography;

namespace SharpObjects.Cryptography.Hash
{
	public class PasswordHash
	{
		// NOTE: changing the following constants will cause
		// incompatibility with previous results, possibliy stored in the database.
		protected const int m_nSize = 24; // this is the number of bytes in the hash array.
		protected readonly static byte[] m_salt = {8, 28, 86}; 

		protected string m_sHash = ""; // number of characters is m_nSize * 2
		protected byte [] m_hash = null;

		public PasswordHash(string sPassword)
		{
			PasswordDeriveBytes p = new PasswordDeriveBytes(sPassword, m_salt);
			m_hash = p.GetBytes(m_nSize);

			StringBuilder sb = new StringBuilder();

			foreach (byte b in m_hash)
			{   
				sb.Append(b.ToString("X"));
			}

			m_sHash = sb.ToString();
		}

		public int Size { get { return m_nSize; } }
		public byte [] BinaryHash { get { return m_hash; } }

		public override string ToString()
		{
			return m_sHash;
		}

		public string Hash{ get { return this.ToString(); } }

		public static implicit operator string (PasswordHash pwd)
		{
			return pwd.ToString();
		}

		public static bool operator == (PasswordHash pwd, string sPasswordHash)
		{
			return pwd.ToString() == sPasswordHash;
		}

		public static bool operator != (PasswordHash pwd, string sPasswordHash)
		{
			return pwd.ToString() != sPasswordHash;
		}

		public static bool operator == (string sPasswordHash, PasswordHash pwd)
		{
			return pwd.ToString() == sPasswordHash;
		}

		public static bool operator != (string sPasswordHash, PasswordHash pwd)
		{
			return pwd.ToString() != sPasswordHash;
		}

		public static bool operator == (PasswordHash pwd1, PasswordHash pwd2)
		{
			return pwd1.ToString() == pwd2.ToString();
		}

		public static bool operator != (PasswordHash pwd1, PasswordHash pwd2)
		{
			return pwd1.ToString() != pwd2.ToString();
		}

		public override bool Equals(object oPwd)
		{
			return this.ToString() == oPwd.ToString();
		}

		public override int GetHashCode()
		{
			return m_sHash.GetHashCode();
		}

	}
}
